---
title: Check whether a User has Access to Something
---

import Mermaid from '@theme/Mermaid'
import RelationTuplePrism from '@theme/RelationTuplePrism'
import CodeTabs from '@theme/CodeTabs'
RelationTuplePrism()

This guide will explain how you can use Ory Keto's
[check-API](../concepts/api-overview.mdx#check-relation-tuple) to determine
whether a [subject](../concepts/subjects.mdx) has a specific
[relation](../concepts/relation-tuples.mdx) on an
[object](../concepts/objects.mdx). The result can be used for controlling access
to specific resources.

## Synchronous Authorization Flow

We recommend offloading the whole burden of access control to Ory Keto.
Typically, this means that the application forwards every incoming request as a
check request to Ory Keto. The following chart demonstrates how such a flow can
look like:

<Mermaid
  chart={`
sequenceDiagram
    participant U as User 'john'
    participant A as Application
    participant K as Ory Keto
%%
    U->>A: decypher(02y_15_4w350m3)
    A->>K: check(messages:02y_15_4w350m3#35;decypher@john)
%%
    alt is allowed
      K-->>A: true
      A-->>U: ory_is_awesome
    else is not allowed
      K-->>A: false
      A-->>U: Error 403
    end
`}
/>

Note that the channel of communication between user <-> application, and
application <-> Ory Keto can vastly differ. The application could offer a JSON
API towards the user, while communicating with Keto through gRPC.

As a first step, the application has to authenticate the user reliably to
provide the subject to Keto. This can be achieved e.g. by using
[Ory Kratos](https://www.ory.sh/kratos/docs/) or any other authentication
system.

The request (here `decypher` of the message `02y_15_4w350m3`) is then translated
into a request to Ory Keto's
[check-API](../concepts/api-overview.mdx#check-relation-tuple). Basically, the
application is asking Keto "Is john allowed to decypher the text
02y_15_4w350m3?"

This question is encoded as the following
[relation tuple](../concepts/relation-tuples.mdx):

```keto-relation-tuples
messages:02y_15_4w350m3#decypher@john
```

:::caution Important

It is up to the application and its defined relation tuples how the check
requests have to be encoded. In this example we assume that the known cypher
messages are stored in Ory Keto and access to the cleartext is encoded by the
`decypher` relation.

:::

### Directly Defined Access

Ory Keto can know the exact relation tuple that the application is checking.
Intuitively, this means that `john` was allowed to `decypher` the message
`02y_15_4w350m3` directly (imagine a "Share with `john`" input in a UI).

Try this yourself by first adding the relation tuple using the
[write API](../concepts/api-overview.mdx#write-apis):

<CodeTabs
  sampleId="simple-access-check-guide/00-write-direct-access"
  version="v0.6.0-alpha.1"
/>

Now, we can use the check-API to verify that `john` is allowed to `decypher` the
message:

<CodeTabs
  sampleId="simple-access-check-guide/01-check-direct-access"
  version="v0.6.0-alpha.1"
/>

### Indirectly Defined Access

On the other hand, it is possible to indirectly grant `john` access to the
resource. This could e.g. be done by adding a group, lets call it `hackers`. Now
we can grant access to the resource to everyone in that group by adding the
following relation tuple to Ory Keto:

```keto-relation-tuples
messages:02y_15_4w350m3#decypher@(groups:hackers#member)
```

We also have to make `john` a `member` of `hackers` by adding the relation
tuple:

```keto-relation-tuples
groups:hackers#member@john
```

Now, when Keto receives above check request, it will resolve the
[subject set](../concepts/subjects.mdx#subject-sets)

```keto-relation-tuples
groups:hackers#member
```

and determine that `john` is a subject in the resulting set. Therefore, it
approves the check request.

There is no limit on the number of indirections through subject sets. It is
however important to follow our
[best practices](./access-control-list-design-best-practices.mdx) to ensure a
good [performance](../performance.mdx).

## Caching Keto's responses

We do not recommend that you cache the responses from Ory Keto. It is designed
to respond quickly and still provide
[some consistency guarantees](../concepts/snaptokens-evaluation-consistency.mdx).
Especially, for the revocation of access it is important to not use a local
cache. Be ensured that Ory Keto heavily utilizes caching wherever possible. If
you still happen to find unacceptably slow check requests, check that you follow
our [best practices](./access-control-list-design-best-practices.mdx) for good
[performance](../performance.mdx), or open an issue if the problem still
persists.

## Conclusion

We learned how to integrate check requests and access control into an
application using Ory Keto's
[check-API](../concepts/api-overview.mdx#check-relation-tuple).
